package ynu.edu.pay.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import ynu.edu.api.dto.PayOrderDTO;
import ynu.edu.common.domain.R;
import ynu.edu.common.exception.BizIllegalException;
import ynu.edu.common.utils.BeanUtils;
import ynu.edu.pay.domain.dto.PayApplyDTO;
import ynu.edu.pay.domain.dto.PayOrderFormDTO;
import ynu.edu.pay.domain.po.PayOrder;
import ynu.edu.pay.domain.vo.PayOrderVO;
import ynu.edu.pay.enums.PayType;
import ynu.edu.pay.service.IPayOrderService;

import java.util.List;

@Api(tags = "支付相关接口")
@RestController
@RequestMapping("pay-orders")
@RequiredArgsConstructor
@Slf4j
@RefreshScope
public class PayController {

    private final IPayOrderService payOrderService;

    @ApiOperation("生成支付单")
    @PostMapping
    public R<String> applyPayOrder(@RequestBody PayApplyDTO applyDTO){
        try {
            log.info("收到创建支付单请求，业务订单号: {}, 支付类型: {}, 金额: {}", 
                    applyDTO.getBizOrderNo(), applyDTO.getPayType(), applyDTO.getAmount());
            
            // 验证支付类型是否支持
            boolean isSupported = PayType.ALIPAY.equalsValue(applyDTO.getPayType()) ||
                                 PayType.WECHAT.equalsValue(applyDTO.getPayType()) ||
                                 PayType.BALANCE.equalsValue(applyDTO.getPayType());
            if(!isSupported){
                log.warn("不支持的支付方式: {}", applyDTO.getPayType());
                return R.error("不支持的支付方式，目前支持：支付宝支付、微信支付、余额支付");
            }
            String payOrderId = payOrderService.applyPayOrder(applyDTO);
            log.info("支付单创建成功，支付单ID: {}, 业务订单号: {}", payOrderId, applyDTO.getBizOrderNo());
            return R.ok(payOrderId);
        } catch (BizIllegalException e) {
            log.error("生成支付单失败，业务异常: {}", e.getMessage());
            return R.error(e.getMessage());
        } catch (Exception e) {
            log.error("生成支付单失败", e);
            return R.error("生成支付单失败: " + e.getMessage());
        }
    }

    @ApiOperation("尝试基于用户余额支付")
    @ApiImplicitParam(value = "支付单id", name = "id")
    @PostMapping("{id}")
    public R<Void> tryPayOrderByBalance(@PathVariable("id") Long id, @RequestBody PayOrderFormDTO payOrderFormDTO){
        try {
            log.info("收到余额支付请求，支付单ID: {}, 请求体ID: {}", id, payOrderFormDTO.getId());
            
            // 验证路径参数和请求体中的ID是否一致
            if (payOrderFormDTO.getId() != null && !id.equals(payOrderFormDTO.getId())) {
                log.error("支付单ID不一致，路径参数: {}, 请求体ID: {}", id, payOrderFormDTO.getId());
                return R.error("支付单ID不一致");
            }
            
            payOrderFormDTO.setId(id);
            payOrderService.tryPayOrderByBalance(payOrderFormDTO);
            log.info("余额支付成功，支付单ID: {}", id);
            return R.ok();
        } catch (BizIllegalException e) {
            log.error("余额支付失败，业务异常: {}", e.getMessage());
            return R.error(e.getMessage());
        } catch (Exception e) {
            log.error("余额支付失败，支付单ID: {}", id, e);
            return R.error("余额支付失败: " + e.getMessage());
        }
    }

    @ApiOperation("查询支付单")
    @GetMapping
    public R<List<PayOrderVO>> queryPayOrders(){
        try {
            List<PayOrderVO> payOrders = BeanUtils.copyList(payOrderService.list(), PayOrderVO.class);
            return R.ok(payOrders);
        } catch (Exception e) {
            log.error("查询支付单失败", e);
            return R.error("查询支付单失败");
        }
    }

    @ApiOperation("根据业务订单id查询支付单")
    @GetMapping("/biz/{id}")
    public R<PayOrderDTO> queryPayOrderByBizOrderNo(@PathVariable("id") Long id){
        try {
            PayOrder payOrder = payOrderService.lambdaQuery().eq(PayOrder::getBizOrderNo, id).one();
            if (payOrder == null) {
                return R.error("支付单不存在");
            }
            PayOrderDTO payOrderDTO = BeanUtils.copyBean(payOrder, PayOrderDTO.class);
            return R.ok(payOrderDTO);
        } catch (Exception e) {
            log.error("查询支付单失败，业务订单ID: {}", id, e);
            return R.error("查询支付单失败");
        }
    }

    @ApiOperation("根据业务订单id查询支付单（内部接口）")
    @GetMapping("/internal/biz/{id}")
    public PayOrderDTO queryPayOrderByBizOrderNoInternal(@PathVariable("id") Long id){
        PayOrder payOrder = payOrderService.lambdaQuery().eq(PayOrder::getBizOrderNo, id).one();
        if (payOrder == null) {
            return null;
        }
        return BeanUtils.copyBean(payOrder, PayOrderDTO.class);
    }

    @ApiOperation("根据支付单ID查询支付单详情")
    @GetMapping("/detail/{id}")
    public R<PayOrderVO> queryPayOrderById(@PathVariable("id") Long id){
        try {
            log.info("查询支付单详情，支付单ID: {}", id);
            PayOrder payOrder = payOrderService.getById(id);
            if (payOrder == null) {
                log.warn("支付单不存在，支付单ID: {}", id);
                return R.error("支付单不存在");
            }
            PayOrderVO payOrderVO = BeanUtils.copyBean(payOrder, PayOrderVO.class);
            log.info("查询支付单成功，支付单ID: {}, 状态: {}, 业务订单号: {}", 
                    id, payOrder.getStatus(), payOrder.getBizOrderNo());
            return R.ok(payOrderVO);
        } catch (Exception e) {
            log.error("查询支付单失败，支付单ID: {}", id, e);
            return R.error("查询支付单失败");
        }
    }
}
